// MonoGame - Copyright (C) MonoGame Foundation, Inc
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.

#pragma once

#include <dxgiformat.h>

#include <api_enums.h>


#define MAX_BACK_BUFFER_COUNT 3

namespace Graphics {

enum class SurfaceType
{
    Texture,
    RenderTarget,
    SwapChainRenderTarget
};

enum class TextureDimension
{
    Texture2D,
    Texture3D,
    TextureCube
};


static constexpr DXGI_FORMAT VertexElementFormatToDXGI_FORMAT[] = {
    DXGI_FORMAT_R32_FLOAT,
    DXGI_FORMAT_R32G32_FLOAT,
    DXGI_FORMAT_R32G32B32_FLOAT,
    DXGI_FORMAT_R32G32B32A32_FLOAT,
    DXGI_FORMAT_R8G8B8A8_UNORM,
    DXGI_FORMAT_R8G8B8A8_UINT,
    DXGI_FORMAT_R16G16_SINT,
    DXGI_FORMAT_R16G16B16A16_SINT,
    DXGI_FORMAT_R16G16_SNORM,
    DXGI_FORMAT_R16G16B16A16_SNORM,
    DXGI_FORMAT_R16G16_FLOAT,
    DXGI_FORMAT_R16G16B16A16_FLOAT,
};

DXGI_FORMAT TextureFormatToDXGI_FORMAT(MGSurfaceFormat tf); // maybe convert this to an array?
DXGI_FORMAT ConvertSRVtoResourceFormat(DXGI_FORMAT format) noexcept; // used by the mip generation

static constexpr DXGI_FORMAT DepthFormatToDXGI_FORMAT[] = {
    DXGI_FORMAT_UNKNOWN,
    DXGI_FORMAT_D16_UNORM,
    DXGI_FORMAT_D24_UNORM_S8_UINT,  // stencil still present
    DXGI_FORMAT_D24_UNORM_S8_UINT
};

static constexpr DXGI_FORMAT DepthFormatToSRV[] = {
    DXGI_FORMAT_UNKNOWN,
    DXGI_FORMAT_R16_UNORM,
    DXGI_FORMAT_R24_UNORM_X8_TYPELESS, // stencil typeless, not readable in shader since it shouldn't be here in the first place
    DXGI_FORMAT_R24G8_TYPELESS // stencil accessed by G channel
};

static constexpr D3D_PRIMITIVE_TOPOLOGY PrimitiveTypeToD3D_PRIMITIVE_TOPOLOGY[] = {
    D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
    D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
    D3D_PRIMITIVE_TOPOLOGY_LINELIST,
    D3D_PRIMITIVE_TOPOLOGY_LINESTRIP,
    D3D_PRIMITIVE_TOPOLOGY_POINTLIST,
};

static constexpr D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTypeToD3D12_PRIMITIVE_TOPOLOGY_TYPE[] = {
    D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE,
    D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE,
    D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE,
    D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE,
    D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT,
};

static constexpr D3D12_FILTER TextureFilterToD3D12_FILTER[] = {
    D3D12_FILTER_MIN_MAG_MIP_LINEAR,
    D3D12_FILTER_MIN_MAG_MIP_POINT,
    D3D12_FILTER_ANISOTROPIC,
    D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT,
    D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR,
    D3D12_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR,
    D3D12_FILTER_MIN_LINEAR_MAG_MIP_POINT,
    D3D12_FILTER_MIN_POINT_MAG_MIP_LINEAR,
    D3D12_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT
};

static constexpr D3D12_TEXTURE_ADDRESS_MODE TextureAddressModeToD3D12_TEXTURE_ADDRESS_MODE[] = {
    D3D12_TEXTURE_ADDRESS_MODE_WRAP,
    D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
    D3D12_TEXTURE_ADDRESS_MODE_MIRROR,
    D3D12_TEXTURE_ADDRESS_MODE_BORDER
};

// TODO:
// TextureFilter
// TextureAddressMode

static constexpr D3D12_COMPARISON_FUNC CompareFunctionToD3D12_COMPARISON_FUNC[] = {
    D3D12_COMPARISON_FUNC_ALWAYS,
    D3D12_COMPARISON_FUNC_NEVER,
    D3D12_COMPARISON_FUNC_LESS,
    D3D12_COMPARISON_FUNC_LESS_EQUAL,
    D3D12_COMPARISON_FUNC_EQUAL,
    D3D12_COMPARISON_FUNC_GREATER_EQUAL,
    D3D12_COMPARISON_FUNC_GREATER,
    D3D12_COMPARISON_FUNC_NOT_EQUAL,
};

static constexpr D3D12_BLEND_OP BlendFunctionToD3D12_BLEND_OP[] = {
    D3D12_BLEND_OP_ADD,
    D3D12_BLEND_OP_SUBTRACT,
    D3D12_BLEND_OP_REV_SUBTRACT,
    D3D12_BLEND_OP_MIN,
    D3D12_BLEND_OP_MAX,
};

static constexpr D3D12_STENCIL_OP StencilOperationToD3D12_D3D12_STENCIL_OP[] = {
    D3D12_STENCIL_OP_KEEP,
    D3D12_STENCIL_OP_ZERO,
    D3D12_STENCIL_OP_REPLACE,
    D3D12_STENCIL_OP_INCR,
    D3D12_STENCIL_OP_DECR,
    D3D12_STENCIL_OP_INCR_SAT,
    D3D12_STENCIL_OP_DECR_SAT,
    D3D12_STENCIL_OP_INVERT,
};

static constexpr D3D12_BLEND BlendToD3D12_BLEND[] = {
    D3D12_BLEND_ONE,
    D3D12_BLEND_ZERO,
    D3D12_BLEND_SRC_COLOR,
    D3D12_BLEND_INV_SRC_COLOR,
    D3D12_BLEND_SRC_ALPHA,
    D3D12_BLEND_INV_SRC_ALPHA,
    D3D12_BLEND_DEST_COLOR,
    D3D12_BLEND_INV_DEST_COLOR,
    D3D12_BLEND_DEST_ALPHA,
    D3D12_BLEND_INV_DEST_ALPHA,
    D3D12_BLEND_BLEND_FACTOR,
    D3D12_BLEND_INV_BLEND_FACTOR,
    D3D12_BLEND_SRC_ALPHA_SAT
};

} // namespace Graphics
